﻿// PhysicsParticle is a 2d circle particle
using Microsoft.Xna.Framework;

using FarseerGames.FarseerPhysics;
using FarseerGames.FarseerPhysics.Collisions;
using FarseerGames.FarseerPhysics.Dynamics;
using FarseerGames.FarseerPhysics.Factories;
using System.Diagnostics;

namespace Organized
{
    // Provides a base object type for physics simulation
    public class PhysicsParticle : Component
    {
       
        // The Body managed by the PhysicsObject
        public Body Body;
        // the physics geometry object
        public Geom Geom;

        public float GroundFriction;
        public float Mass;

        public PhysicsSimulator Simulator;

        //collision caterogy this object collides with
        public CollisionCategory CollidesWith;
        //collision categoy this object belongs to
        public CollisionCategory CollisionCategories;

        // The PhysicsObject's position
        public Vector2 Position
        {
            get { return Body.Position; }
            set { Body.Position = value; }
        }

        // The PhysicsObject's rotation as a Matrix
        public float Rotation
        {
            get { return Body.Rotation; }           
        }

        
        // Whether or not the physics object is locked in place
        public bool IsStatic
        {
            get { return Body.IsStatic; }
            set { Body.IsStatic = value; }
        }  

        // The body's velocity
        public Vector2 Velocity
        {
            get { return Body.GetVelocityAtLocalPoint(new Vector2(0, 0)); }            
        }

        public float Radius;

      
       
        // Constructors
        //public PhysicsParticle() : base() { }
        public PhysicsParticle(PhysicsSimulator _physicsSimulator, Vector2 _position, float _bodyRadius, float _bodyMass, float _groundFriction, float _bouncyness, float _surfaceFriction, bool _isStatic, GameScreen Parent) : base(Parent) 
        {

            Simulator = _physicsSimulator;
            Body = BodyFactory.Instance.CreateCircleBody(_physicsSimulator, _bodyRadius, _bodyMass);
            Radius = _bodyRadius;
            Mass = _bodyMass;
            
            
            Position = _position;
            Body.IsStatic = _isStatic;
            //Air friction to simulate ground friction
           
            
            Geom = GeomFactory.Instance.CreateCircleGeom(_physicsSimulator, Body, _bodyRadius, 20);
          
            //store ground friction
           

            //setup parameters if we are not static
            if (!Body.IsStatic)
            {
                Body.LinearDragCoefficient = _groundFriction; // 'air'friction providing Y dimensional ground friction
                Geom.RestitutionCoefficient = _bouncyness;   //bouncyness
                Geom.FrictionCoefficient = _surfaceFriction;   //collision friction
              
                GroundFriction = Body.LinearDragCoefficient;
            }        
   
            //Set Collision Categories According to object Radius
            SetCategoriesFromRadius(_bodyRadius);
        }


        //set collision categories

        private void SetCategoriesFromRadius(float radius)
        {
            //Cat31 is no collision -> sensors
            if (radius <= 10)
            {
               
                CollisionCategories = CollisionCategory.Cat1;
                CollidesWith = CollisionCategory.Cat1 | CollisionCategory.Cat2 | CollisionCategory.Cat3 | CollisionCategory.Cat4;
               
                
            }
            else if (radius <= 20)
            {
               
                CollisionCategories = CollisionCategory.Cat2;
                CollidesWith = CollisionCategory.Cat1 | CollisionCategory.Cat2 | CollisionCategory.Cat3  | CollisionCategory.Cat10;
            }
           
            else
            {
                CollisionCategories = CollisionCategory.Cat3;
                CollidesWith = CollisionCategory.Cat1 | CollisionCategory.Cat2 | CollisionCategory.Cat3  | CollisionCategory.Cat10 | CollisionCategory.Cat11;
            }


            Geom.CollisionCategories = CollisionCategories;
            Geom.CollidesWith = CollidesWith;
            
        }

        public void SetCollideWithFromHeight(float height)
        {
            //Cat31 is no collision -> sensors
            //reset categories
            CollisionCategories = new CollisionCategory();
            CollidesWith = new CollisionCategory();

            if (height <= 20)
            {
                //Trace.WriteLine("on surface");
                CollisionCategories = CollisionCategory.Cat1;
                CollidesWith = CollisionCategory.Cat1 | CollisionCategory.Cat2 | CollisionCategory.Cat3;
            }
            else if (height <= 40)
            {
                CollisionCategories = CollisionCategory.Cat10;
                //Trace.WriteLine("ignore Cat 1");
                CollidesWith = CollisionCategory.Cat2 | CollisionCategory.Cat3; //rule out 1
            }                
           
            //for big buildings you cant fly over
            else
            {
                CollisionCategories = CollisionCategory.Cat11;
                //Trace.WriteLine("ignore Cat 1 & 2 & 3");
                CollidesWith = CollisionCategory.Cat3; //rule out 1 2 3
            }

          
          
            Geom.CollisionCategories = new CollisionCategory();
            Geom.CollisionCategories = CollisionCategories;
            Geom.CollidesWith = new CollisionCategory();
            Geom.CollidesWith = CollidesWith;


        }

        
         


        

        

        // Disposes physics body and component
        public override void DisableComponent()
        {
            Body.Dispose();
            Geom.Dispose();
            base.DisableComponent();
        }
    }
}